/*
 * @Author: 吴世扬 18368095041@163.com
 * @Date: 2022-09-13 09:48:59
 * @LastEditors: 吴世扬 18368095041@163.com
 * @LastEditTime: 2022-11-15 17:56:47
 * @FilePath: /vuecli508-datav/src/components/ui/ol-map/mixin/judgePolygonWithCenterIn.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
// import ol from 'ol';
import { Feature } from 'ol';
import { Style, Fill } from 'ol/style';
import { Circle } from 'ol/geom';
import { debounce } from '../utils/index';

export default {
    data() {
        return {
            moveendFns: [] // 移动结束所有回调函数
        };
    },
    created() {
        const judgePolygonWithCenterIn = debounce(() => {
            if (this.isDebug) {
                this.addCenterCircle();
            }
            const result = this.getFeatureWithCenterIn();
            this.$emit('featureWithCenterIn', result);
        }, 500);
        this.eventCallbackMap['moveend'].push(judgePolygonWithCenterIn);
    },
    methods: {
        // 提供给外部使用设置焦点多边形
        setFocusFeature(feature, option) {
            const { focusFeature } = this.polygonNsp;
            // 去除之前的聚焦样式
            if (focusFeature) {
                const { index } = focusFeature.getProperties();
                const style = this.createFeatureStyle(this.polygonsData[index]);
                focusFeature.setStyle(style);
            }
            // 存在则设置聚焦样式
            if (feature && option) {
                const style = this.createFeatureStyle(option);
                feature.setStyle(style);
                this.polygonNsp.focusFeature = feature;
            }
        },
        // 测试用-显示中心标记
        addCenterCircle() {
            if (this.centerFeature) {
                this.markersLayer.getSource().removeFeature(this.centerFeature);
            }
            const center = this.view.getCenter();
            // console.log(center);
            this.centerFeature = new Feature({
                geometry: new Circle(center, 0.0001),
                name: 'center'
            });
            this.centerFeature.setStyle(
                new Style({
                    fill: new Fill({
                        color: 'yellow'
                    })
                })
            );
            // debugger
            this.markersLayer.getSource().addFeature(this.centerFeature);
        },
        // 获取中心点所在的多边形
        getFeatureWithCenterIn() {
            const features = this.polygonNsp.layer.getSource().getFeatures();
            const len = features.length;
            const center = this.view.getCenter();
            const point = {
                x: center[0],
                y: center[1]
            };
            for (let i = 0; i < len; i++) {
                const { index } = features[i].getProperties();
                const xyPolygons = this.polygonsData[index].polygon.map(
                    (item) => ({
                        x: item.lng,
                        y: item.lat
                    })
                );
                if (this.isInPolygon(xyPolygons, point.x, point.y)) {
                    return {
                        data: this.polygonsData[index],
                        feature: features[i],
                        mapInstance: this
                    };
                }
            }
            return false;
        },
        // 点是否在多边形内
        isInPolygon(points, x, y) {
            if (!points || !x || !y) return false;
            const len = points.length;
            let w = 0;
            // const point = new T.Point(lng, lat);
            // debugger;
            for (let i = 0, j = len - 1; i < len; i++) {
                const select = points[j];
                const next = points[i];
                w += this.windingLine(select.x, select.y, next.x, next.y, x, y);
                j = i;
            }
            return w !== 0;
        },
        // winding number算法(https://baike.baidu.com/item/%E5%8D%B7%E7%BB%95%E6%95%B0/58369304)-判断点是否在多边形内
        windingLine(x0, y0, x1, y1, x, y) {
            if ((y > y0 && y > y1) || (y < y0 && y < y1)) {
                return 0;
            }
            if (y1 === y0) {
                return 0;
            }
            const dir = y1 < y0 ? 1 : -1;
            const t = (y - y0) / (y1 - y0);
            const ex = t * (x1 - x0) + x0;
            return ex > x ? dir : 0;
            // return (y - y0)(x1 - x0) > (x - x0)(y1 - y0)
        }
    }
};
